#include "qtsnake.h"
#include "ui_qtsnake.h"

QtSnake::QtSnake(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::QtSnake),blsRun(false)
{
    ui->setupUi(this);
    this->setGeometry(QRect(600,300,840,590));
    this->setWindowTitle("双人贪吃蛇");
    this->setWindowIcon(QPixmap("://images/Snake_ui.jpg"));
}

QtSnake::~QtSnake()
{
    delete ui;
}

QRect QtSnake::CreateFood()
{
    int x,y;
    x=qrand()%25;
    y=qrand()%25;//随机生成小于25的整数
    if(QPoint(20+x*20,20+y*20)==SnakeHead1.topLeft()||QPoint(20+x*20,20+y*20)==SnakeHead2.topLeft())
        food=CreateFood();//再次生成一个新食物
    QRect rect(20+x*20,20+y*20,20,20);//设置食物小方块位置
    return rect;
}

void QtSnake::paintEvent(QPaintEvent *event)
{//update()或程序第一次启动时自动执行，用于画图
    QPainter painter(this);
    if(!blsRun)//重开时执行
    initSnake();//初始化蛇
    //画游戏背景：
    //外墙
    painter.setPen(Qt::black);//设置画笔颜色
    painter.setBrush(Qt::gray);//设置填充颜色
    painter.drawRect(15,15,510,510);//画矩形，相对于窗体的起点坐标(15,15),大小510*510
    //内墙
    painter.setPen(Qt::black);//设置画笔颜色
    painter.setBrush(Qt::black);//设置填充颜色
    painter.drawRect(20,20,500,500);//画矩形，相对于窗体的起点坐标(20,20),大小500*500
    painter.drawPixmap(20,20,500,500,QPixmap("://images/BeiJing.jpg"));

    //显示游戏的开始和结束
    QFont font1("Courier",2);
    painter.setFont(font1);
    painter.setPen(Qt::red);
    painter.setBrush(Qt::red);
    painter.drawText(40,150,ifDisplay);

    //显示得分
    QFont font2a("Courier",15);
    QFont font2b("Courier",15);
    painter.setFont(font2a);
    painter.setFont(font2b);
    painter.setPen(Qt::blue);
    painter.setBrush(Qt::blue);
    painter.drawText(40,570,scoreLabel1);
    painter.drawText(240,570,scoreLabel2);
    painter.drawText(180,570,QString::number(Score1));
    painter.drawText(380,570,QString::number(Score2));


    //显示规则
    QFont font3("Courier",30);
    painter.setFont(font3);
    painter.setPen(Qt::black);
    painter.setBrush(Qt::black);
    painter.drawText(560,70,rule1);
    painter.drawText(560,100,rule2);
    painter.drawText(560,150,rule3);
    painter.drawText(560,180,rule4);
    painter.drawText(560,230,rule5);
    painter.drawText(560,260,rule6);

    //画蛇
    painter.setPen(Qt::black);//设置画笔颜色
    painter.setBrush(Qt::green);//设置填充颜色
    painter.drawRects(&vSnakeRect1[0],vSnakeRect1.size());//画n个小方块作为蛇1
    painter.setPen(Qt::black);//设置画笔颜色
    painter.setBrush(Qt::yellow);//设置填充颜色
    painter.drawRects(&vSnakeRect2[0],vSnakeRect2.size());//画n个小方块作为蛇2

    //画食物
    painter.setPen(Qt::black);//设置画笔颜色
    painter.setBrush(Qt::red);//设置填充颜色
    painter.drawPixmap(food,QPixmap("://images/food.png"));
    if(blsOver)
        timer->stop();//游戏结束，停止计时器
}

void QtSnake::initSnake()
{
    rule1="玩家1:";
    rule2="按↑↓→←键移动";
    rule3="玩家2:";
    rule4="按wsda键移动";
    rule5="先吃到5个的获胜";
    rule6="按空格暂停，其他键继续";
    newDirection1=2;//默认向下运动
    newDirection2=2;//默认向下运动
    blsRun=true;//开始运行
    blsOver=false;//结束运行
    ifDisplay="游戏开始";
    scoreLabel1="玩家1得分：";
    scoreLabel2="玩家2得分：";
    Score1=0;
    Score2=0;
    food=CreateFood();//创建食物

    vSnakeRect1.resize(5);
    vSnakeRect2.resize(5);//初始化蛇的长度为5
    for(int i=0;i<vSnakeRect1.size();i++)//用for循环初始化vector
    {
        QRect rect(120,60+20*i,20,20);//生成蛇的初始位置
        vSnakeRect1[vSnakeRect1.size()-1-i]=rect;//赋值小方块到容器
    }
    for(int i=0;i<vSnakeRect2.size();i++)//用for循环初始化vector
    {
        QRect rect(380,60+20*i,20,20);//生成蛇的初始位置
        vSnakeRect2[vSnakeRect2.size()-1-i]=rect;
    }
    SnakeHead1=vSnakeRect1.first();//指定蛇头1
    SnakeHead2=vSnakeRect2.first();//指定蛇头2
    //计时器事件
    timer=new QTimer(this);//设定计时器
    timer->start(250);//计时器时间是1s
    connect(timer,SIGNAL(timeout()),SLOT(placeUpdate()));//信号连接槽，发出信号的是timer，信号是timeout，执行的槽是placrUpdate
}

void QtSnake::keyPressEvent(QKeyEvent *event)//键盘事件
{
    QKeyEvent *key=(QKeyEvent*)event;
    switch(key->key())
    {
    case Qt::Key_Up:newDirection1=1;//1代表上
        break;
    case Qt::Key_Down:newDirection1=2;//2代表下
        break;
    case Qt::Key_Left:newDirection1=3;//3代表左
        break;
    case Qt::Key_Right:newDirection1=4;//4代表右
        break;
    case Qt::Key_W:newDirection2=1;//1代表上
        break;
    case Qt::Key_S:newDirection2=2;//2代表下
        break;
    case Qt::Key_A:newDirection2=3;//3代表左
        break;
    case Qt::Key_D:newDirection2=4;//4代表右
        break;
    case Qt::Key_Space:timer->stop();//空格键暂停
        break;
    default:timer->start(500);//其他键重新计时;
    }
}
void QtSnake::placeUpdate()//蛇的移动，坐标变换
{
    ifDisplay="";//否则将会一直显示
    SnakeHead1=vSnakeRect1.first();
    SnakeHead2=vSnakeRect2.first();//确定蛇头
    IfEat();
    IfHit();
    IfWin();
    for(int i=0;i<vSnakeRect1.size()-1;i++)
        vSnakeRect1[vSnakeRect1.size()-1-i]=vSnakeRect1[vSnakeRect1.size()-2-i];
    for(int i=0;i<vSnakeRect2.size()-1;i++)
        vSnakeRect2[vSnakeRect2.size()-1-i]=vSnakeRect2[vSnakeRect2.size()-2-i];//让除了蛇头的数组小方块移动，从后到前
        switch(newDirection1)//根据按键改变蛇头1移动方向
    {
    case 1:
        SnakeHead1.setTop(SnakeHead1.top()-20);
        SnakeHead1.setBottom(SnakeHead1.bottom()-20);
        break;
    case 2:
        SnakeHead1.setTop(SnakeHead1.top()+20);
        SnakeHead1.setBottom(SnakeHead1.bottom()+20);
        break;
    case 3:
        SnakeHead1.setLeft(SnakeHead1.left()-20);
        SnakeHead1.setRight(SnakeHead1.right()-20);
        break;
    case 4:
        SnakeHead1.setLeft(SnakeHead1.left()+20);
        SnakeHead1.setRight(SnakeHead1.right()+20);
        break;
    default:;
    }
        switch(newDirection2)//根据按键改变蛇头2移动方向
    {
    case 1:
        SnakeHead2.setTop(SnakeHead2.top()-20);
        SnakeHead2.setBottom(SnakeHead2.bottom()-20);
        break;
    case 2:
        SnakeHead2.setTop(SnakeHead2.top()+20);
        SnakeHead2.setBottom(SnakeHead2.bottom()+20);
        break;
    case 3:
        SnakeHead2.setLeft(SnakeHead2.left()-20);
        SnakeHead2.setRight(SnakeHead2.right()-20);
        break;
    case 4:
        SnakeHead2.setLeft(SnakeHead2.left()+20);
        SnakeHead2.setRight(SnakeHead2.right()+20);
        break;
    default:;
    }
    vSnakeRect1[0]=SnakeHead1;
    vSnakeRect2[0]=SnakeHead2;//将第一个节点设置为蛇头位置
    if(SnakeHead1.top()<20||SnakeHead1.bottom()>520||SnakeHead1.left()<20||SnakeHead1.right()>520)
    {
        ifDisplay="游戏结束，恭喜玩家2获胜";
        blsOver=true;
    }
    if(SnakeHead2.top()<20||SnakeHead2.bottom()>520||SnakeHead2.left()<20||SnakeHead2.right()>520)
    {
        ifDisplay="游戏结束，恭喜玩家1获胜";
        blsOver=true;
    }
    update();//更新paintEvent
}

void QtSnake::IfEat()
{
    if(SnakeHead1==food)
    {
        SnakeHead1=food;//食物变为蛇头1
        vSnakeRect1.push_back(vSnakeRect1.last());//再次加入最后一个节点到容器，增长蛇身1
        food=CreateFood();//再次生成一个新食物
        Score1+=10;//吃到一个食物加10分
    }
    if(SnakeHead2==food)
    {
        SnakeHead2=food;//食物变为蛇头2
        vSnakeRect2.push_back(vSnakeRect2.last());//再次加入最后一个节点到容器，增长蛇身2
        food=CreateFood();//再次生成一个新食物
        Score2+=10;//吃到一个食物加10分
    }
}

void QtSnake::IfHit()
{
    for(int i=1;i<vSnakeRect1.size();i++)//遍历蛇身
    {
        if(SnakeHead1==vSnakeRect1[i])//是否撞到自己
        {
            ifDisplay="游戏结束，恭喜玩家2获胜";
            blsOver=true;
            update();
        }
    }
    for(int i=0;i<vSnakeRect1.size();i++)//遍历蛇身
    {
        if(SnakeHead2==vSnakeRect1[i])//是否被撞
        {
            ifDisplay="游戏结束，恭喜玩家1获胜";
            blsOver=true;
            update();
        }

    }
    for(int i=1;i<vSnakeRect2.size();i++)//遍历蛇身
    {
        if(SnakeHead2==vSnakeRect2[i])//是否撞到自己
        {
            ifDisplay="游戏结束，恭喜玩家1获胜";
            blsOver=true;
            update();
        }
    }
    for(int i=0;i<vSnakeRect2.size();i++)//遍历蛇身
    {
        if(SnakeHead1==vSnakeRect2[i])//是否被撞
        {
            ifDisplay="游戏结束，恭喜玩家2获胜";
            blsOver=true;
            update();
        }
    }
}

void QtSnake::IfWin()
{
    if(Score1==50)
    {
        ifDisplay="游戏结束，恭喜玩家1获胜";
        blsOver=true;
        update();
    }

    if(Score2==50)
    {
        ifDisplay="游戏结束，恭喜玩家1获胜";
        blsOver=true;
        update();
    }
}
